package logic

import (
	"card/app/models"
	"card/app/requests"
	"card/dao"
	"card/pkg/logger"
	"card/pkg/myError"
	"card/pkg/util"
	"context"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"time"
)

type MemberLogic struct {
	ctx context.Context
	ip  string
}

const (
	DisabledStatus = -1 //禁用
	EnableStatus   = 1  //启用
	Member         = 0  //默认会员
	Agent          = 1  //代理
)

func NewMember(ctx context.Context) *MemberLogic {
	ip := ""
	if c, ok := ctx.(*gin.Context); ok {
		ctx = c.Request.Context()
		ip = c.ClientIP()
	}
	return &MemberLogic{ctx: ctx, ip: ip}
}

func (l *MemberLogic) GetMemberById(id string) (*models.Member, error) {
	member := models.NewMemberRepo(l.ctx)
	info, err := member.One(dao.WithWhere("id", id))
	if err != nil {
		return nil, myError.WarpError(err)
	}
	return &info, nil
}
func (l *MemberLogic) RegisterByEmail(params *requests.RegisterByEmailRequest) error {
	var (
		memberInfo models.Member
		err        error
	)
	memberModel := models.NewMemberRepo(l.ctx)
	pid := int64(0)
	if params.InviteCode != "" {
		memberInfo, err = memberModel.One(dao.WithWhere("invite_code = ?", params.InviteCode))
		if err != nil {
			return myError.WarpError(err)
		}
		if memberInfo.ID > 0 {
			pid = memberInfo.ID
		}
	}
	memberInfo, err = memberModel.One(dao.WithWhere("email = ?", params.Email))
	if err != nil {
		return myError.WarpError(err)
	}
	if memberInfo.ID > 0 {
		return myError.WarpValidate("邮箱已经存在")
	}
	memberInfo.Email = params.Email
	memberInfo.LoginIp = l.ip
	memberInfo.CreatedAt = models.LocalTime(time.Now())
	memberInfo.Password = params.Password
	memberInfo.InviteCode = util.RandomString(5)
	memberInfo.Status = EnableStatus
	memberInfo.IsAgent = Agent
	lastId, err := memberModel.Create(&memberInfo)
	if err != nil {
		return myError.WarpError(err)
	}
	if lastId > 0 && pid > 0 {
		go func() {
			memberTealLevelLogic := NewMemberLevelLogic(context.Background())
			//只需要三级分销
			arr, err := memberTealLevelLogic.GetTeamList(pid, lastId, 0, 0, 0)
			if err != nil {
				logger.Error(nil, "[注册]设置分销关系错误", zap.String("email", params.Email), zap.Error(err))
				return
			}
			memberLeveRepo := models.NewMemberLevelRepo(context.Background())
			total, err := memberLeveRepo.Insert(arr)
			if err != nil {
				logger.Error(nil, "[注册]保存分销关系错误", zap.String("email", params.Email), zap.Error(err))
				return
			}
			logger.Info(nil, "[注册]保存分销关系成功", zap.Int64("total", total))
		}()
	}
	return nil
}

func (l *MemberLogic) Login(params *requests.LoginRequest) (int64, error) {
	var (
		err        error
		memberInfo models.Member
	)
	memberModel := models.NewMemberRepo(l.ctx)
	if params.Email != "" {
		memberInfo, err = memberModel.One(dao.WithWhere("email = ?", params.Email))
	} else if params.Tel != "" {
		memberInfo, err = memberModel.One(dao.WithWhere("tel = ?", params.Tel))
	} else {
		err = myError.WarpValidate("请输入账号")
	}
	if err != nil {
		return 0, err
	}
	if memberInfo.ID == 0 {
		return 0, myError.WarpValidate("账号或密码不正确")
	}
	if memberInfo.Status == DisabledStatus {
		return 0, myError.WarpValidate("该账号已经禁用，请联系管理员")
	}
	if !util.BcryptCheck(params.Password, memberInfo.Password) {
		return 0, myError.WarpValidate("账号或密码不正确")
	}
	updateData := map[string]interface{}{
		"login_ip":   l.ip,
		"login_time": time.Now().Format(time.DateTime),
	}
	err = memberModel.Save(memberInfo.ID, updateData)
	if err != nil {
		return 0, myError.WarpError(err)
	}
	return memberInfo.ID, nil
}
func (l *MemberLogic) CurrentUser() (one models.Member) {
	one = l.ctx.Value("user").(models.Member)
	return
}

func (l *MemberLogic) CurrentUserId() int64 {
	return l.ctx.Value("user_id").(int64)
}

func (l *MemberLogic) UpdateUserInfo(params *requests.MemberUpdateRequest) error {
	memberModel := models.NewMemberRepo(l.ctx)
	updateData := make(map[string]interface{})
	userId := l.CurrentUserId()
	if params.Tel != "" {
		memberInfo, err := memberModel.One(dao.WithWhere("tel = ? and id !=?", params.Tel, userId))
		if err != nil {
			return myError.WarpError(err)
		}
		if memberInfo.ID > 0 {
			return myError.WarpValidate("电话号码已经存在")
		}
		updateData["tel"] = params.Tel
	}
	if params.Avatar != "" {
		updateData["avatar"] = params.Avatar
	}
	if params.Password != "" && params.Password == params.ConfirmPassword {
		updateData["password"] = util.BcryptHash(params.Password)
	}
	err := memberModel.Save(userId, updateData)
	if err != nil {
		return myError.WarpError(err)
	}
	return nil
}
